package 算法练习;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @version 1.0
 * @author： li
 * @date： 2022-01-01 16:27
 */
/* 问题描述
　　给定一个1～N的排列a[i]，每次将相邻两个数相加，得到新序列，再对新序列重复这样的操作，显然每次得到的序列都比上一次的序列长度少1，最终只剩一个数字。
　　例如:
　　3 1 2 4
　　4 3 6
　　7 9
　　16
　　现在如果知道N和最后得到的数字sum，请求出最初序列a[i]，为1～N的一个排列。若有多种答案，则输出字典序最小的那一个。数据保证有解。
输入格式
　　第1行为两个正整数n，sum
输出格式
　　一个1～N的一个排列
样例输入
4 16
样例输出
3 1 2 4
数据规模和约定
　　0<n<=10*/
public class 数字游戏_回溯_最佳 {
    static int sum;
    static int N;
    static boolean bool = true;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        N = input.nextInt();
        sum = input.nextInt();
        //保存全排序数组
        int[] array = new int[N];
        int[] visit = new int[N + 1];
        dfs(0, array, visit);
        input.close();
    }
    public static void dfs(int step, int[] arr, int[] vis) {
        // System.out.println(Arrays.toString(arr));
        // System.out.println(Arrays.toString(vis));
        // System.out.println(" ");
        if (step == N) {
            int[] arr1 = new int[N];
            System.arraycopy(arr, 0, arr1, 0, N);
            for (int i = 1; i < N; i++) {
                for (int j = 0; j < N - i; j++) {
                    arr1[j] = arr1[j] + arr1[j + 1];
//                    System.out.println(arr1[j]);
                }
            }
            if (arr1[0] == sum) {
                for (int x : arr) {
                    System.out.print(x + " ");
                }
                bool = false;

            }
            return;
        }
        if (bool) {
            for (int i = 1; i <= N; i++) {
                if (vis[i] == 0){
                    arr[step] = i;
                    vis[i] = 1;
                    dfs(step + 1, arr, vis);
                    vis[i] = 0;
                }

            }
        }
    }
}
